//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __POOL_MANAGER_INCLUDED__
#define __POOL_MANAGER_INCLUDED__

#include "irrTypes.h"
#include "irrArray.h"
#include "../Core/Commons.h"

//template <class T>
//class pool
//{
//	public:
//		pool() {m_pool.clear();};
//		~pool() {m_pool.clear();};
//
//
//		void InitPool(irr::u32 size)
//		{			
//			m_pool.set_used(size);
//
//			for (irr::u32 i = 0 ; i < m_pool.size() ; i ++ )
//			{
//				m_pool[i] = new T;
//			}
//
//			m_used.set_used(size);
//
//			for (irr::u32 i = 0 ; i < m_used.size() ; i ++ )
//			{
//				m_used[i] = false;
//			}
//		}	
//
//		void ClearPool()
//		{
//			for (irr::u32 i = 0 ; i < m_pool.size() ; i ++ )
//			{		
//				T* obj = m_pool[i];
//				SAFE_DEL(obj);
//			}
//			
//			m_pool.clear();
//
//			for (irr::u32 i = 0 ; i < m_used.size() ; i ++ )
//			{
//				m_used[i] = false;
//			}
//
//			m_used.clear();
//		}
//
//		
//		T* GetFreeObject()
//		{
//			for (irr::u32 i = 0 ; i < m_used.size() ; i ++ )
//			{
//				if (!m_used[i])
//				{
//					m_used[i] = true;
//					m_pool[i]->Reset();
//					return m_pool[i];
//				}
//			}
//
//			return NULL;
//		}
//
//		void FreeObject(T* o)
//		{
//			for (irr::u32 i = 0 ; i < m_pool.size() ; i ++ )
//			{
//				if (m_pool[i] == o)
//				{
//					m_used[i] = false;
//				}
//			}
//		}
//
//		const irr::core::array<T*>&	GetPoolObjects()		{return m_pool;}
//		bool						IsUsed(irr::s32 index)	{return m_used[index];}
//
//	private:
//
//	irr::core::array<T*> m_pool;
//	irr::core::array<bool> m_used;
//};
class CPoolPara
{
public:
	CPoolPara(){};
	~CPoolPara(){};

	int m_nType;
};
//by linhai 2010.06.01
template <class T>
class pool
{
	public:
		pool() { m_nMaxCount = 0; m_pool.clear();};
		~pool() {m_pool.clear();};

		virtual void init(int nNum)
		{
		}
		void InitPool(irr::u32 size)
		{		
			m_nMaxCount = size;
			m_pool.set_used(m_nMaxCount);
			
			//for (irr::u32 i = 0 ; i < m_pool.size() ; i ++ )
			//{
			//	m_pool[i] = new T;
			//}

			m_used.set_used(m_nMaxCount);

			for (irr::u32 i = 0 ; i < m_nMaxCount ; i ++ )
			{
				m_used[i] = -1;
			}

			//m_pool[0] = new T;
			//init(0);
			//m_used[0] = 0;
		}	

		void ClearPool()
		{
			for (irr::u32 i = 0 ; i < m_nMaxCount ; i ++ )
			{	
				if(m_used[i]>=0)
				{
					T* obj = m_pool[i];
					SAFE_DEL(obj);
				}
				m_used[i] = -1;
			}
			
			m_pool.clear();

			//for (irr::u32 i = 0 ; i < m_used.size() ; i ++ )
			//{
			//	m_used[i] = false;
			//}

			m_used.clear();
		}

		
		T* GetFreeObject()
		{
			for (irr::u32 i = 0 ; i < m_nMaxCount ; i ++ )
			{
				if (m_used[i]==0)
				{
					m_used[i] = 1;
					m_pool[i]->Reset();
					return m_pool[i];
				}
				else if (m_used[i]==-1)
				{
					m_pool[i] = new T;
					init(i);
					m_pool[i]->Reset();
					m_used[i] = 1;
					return m_pool[i];
				}
			}

			return NULL;
		}

		void FreeObject(T* o)
		{
			for (irr::u32 i = 0 ; i < m_nMaxCount ; i ++ )
			{
				if (m_used[i] == 1)
				{
					if (m_pool[i] == o)
					{
						m_used[i] = 0;
					}
				}
			}
		}

		const irr::core::array<T*>&	GetPoolObjects()		{return m_pool;}
		int	  GetMaxCount(){return m_nMaxCount;}
		bool						IsUsed(irr::s32 index)	{return m_used[index]>0;}

	protected:

	irr::core::array<T*> m_pool;
	irr::core::array<int> m_used;
	int m_nMaxCount;
};
//by linhai 2010.04.21
#define DECLARE_POOL(PoolName,className) \
class PoolName : public pool<className> \
{  \
}; 
#define DECLARE_POOL_PARA(PoolName,className) \
class PoolName : public pool<className> \
{  \
public:\
	PoolName(){m_pPara = NULL; }\
	~PoolName(){if(m_pPara){delete m_pPara;m_pPara=NULL;}}\
	void init(int nNum)\
	{\
		if(m_pPara)\
		{\
			m_pool[nNum]->InitPoolProp(m_pPara);\
		}\
	}\
	void InitPool(irr::u32 size,CPoolPara* pPara=NULL)	\
	{	\
		pool<className>::InitPool(size);	\
		m_pPara = pPara;\
	}	\
	CPoolPara* m_pPara;\
}; 
#define SAFE_DEL_POOL(pPool) {if(pPool){pPool->ClearPool();SAFE_DEL(pPool);}}
#define UPDATEWEAPONPOOLS(classname,objectname,ts) \
{ \
	if(objectname) \
	{\
		const array<classname*>& _obj = objectname->GetPoolObjects();\
		for (int i=0; i < objectname->GetMaxCount(); i++ )\
		{\
			if (objectname->IsUsed(i))\
			{\
				_obj[i]->Update(ts);\
			}\
		}\
	}\
}

#endif //__POOL_MANAGER_INCLUDED__
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////